<template>

  <div class="common-layout">
    <el-container>
      <el-aside width="40%" :style="{height : windowHeight + 'px'}">
        请选择表：
        <el-select v-model="tableName" filterable placeholder="请选择表" @change="tableChange">
          <el-option v-for="item in tableNameOptions" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
        <el-button style="margin-left: 60px;" type="primary" @click="scdm">生成代码</el-button>
        <el-button type="primary" style="margin-left: 16px" @click="drawer = true">
          切换数据源
        </el-button>
        <el-table :data="tableData" style="width: 100%;margin-top: 30px;" @selection-change="handleSelectionChange">
          <el-table-column type="selection" width="55" />
          <el-table-column type="index" width="50" />
          <el-table-column prop="name" label="字段名" width="120" />
          <el-table-column prop="type" label="类型" width="180" />
          <el-table-column prop="size" label="字段大小" width="100" />
          <el-table-column prop="comment" label="注释" width="180" />
        </el-table>
      </el-aside>
      <el-container>
        <div class="parent">
          <div class="div1">
            实体类
            <div style="position:relative">
              <el-input v-model="entity" type="textarea" :rows="14" />
              <el-icon @click="copyAnswer(entity)" style="float: right; position: absolute; right:10px; top: 10px">
                <DocumentCopy />
              </el-icon>
            </div>
          </div>
          <div class="div2">
            新增时候代码
            <div style="position:relative">
              <el-input v-model="insertText" type="textarea" :rows="14" />
              <el-icon @click="copyAnswer(insertText)" style="float: right; position: absolute; right:10px; top: 10px">
                <DocumentCopy />
              </el-icon>
            </div>
          </div>
          <div class="div3">
            修改时候代码
            <div style="position:relative">
              <el-input v-model="updateText" type="textarea" :rows="14" />
              <el-icon @click="copyAnswer(updateText)" style="float: right; position: absolute; right:10px; top: 10px">
                <DocumentCopy />
              </el-icon>
            </div>
          </div>
        </div>
      </el-container>

    </el-container>

    <el-drawer v-model="drawer" :direction="direction">
      <template #header>
        <h4>请切换自己的数据库-sqlserver</h4>
      </template>
      <template #default>
        <div>
          <el-form :label-position="labelPosition" label-width="100px" :model="formLabelAlign" style="max-width: 460px">
            <el-form-item label="数据库ip">
              <el-input v-model="formLabelAlign.ip" placeholder="请输入数据库ip" />
            </el-form-item>
            <el-form-item label="端口">
              <el-input v-model="formLabelAlign.port" placeholder="请输入数据库端口" />
            </el-form-item>
            <el-form-item label="数据库名称">
              <el-input v-model="formLabelAlign.name" placeholder="请输入数据库名称" />
            </el-form-item>
            <el-form-item label="账号">
              <el-input v-model="formLabelAlign.username" placeholder="请输入数据库用户名" />
            </el-form-item>
            <el-form-item label="密码">
              <el-input type="password" v-model="formLabelAlign.password" show-password placeholder="请输入数据库密码" />
            </el-form-item>
          </el-form>
          <el-button style="margin-left: 60px;" type="primary" @click="cheshi">切换连接</el-button>
        </div>
      </template>
    </el-drawer>
  </div>

</template>

<script setup>
  import { ref, reactive, toRefs, onMounted } from "vue";
  import { List, Info, Danqiansql, Qiehuansql } from "@/api/sqlserver/sqlTable";
  import { ElMessageBox, ElNotification, ElMessage } from 'element-plus'
  import useClipboard from 'vue-clipboard3'
  const { toClipboard } = useClipboard()

  const state = reactive({
    tableNameOptions: [],
  });
  const tableNameOptions = ref("");
  const tableName = ref("");
  const tableData = ref("");
  const windowHeight = ref("");
  const multipleSelection = ref([])
  const entity = ref("")
  const insertText = ref("")
  const updateText = ref("")
  //抽屉
  const drawer = ref(false)
  const direction = ref('ltr')
  //form表单
  const labelPosition = ref('right')
  const formLabelAlign = reactive({
    ip: '',
    port: '',
    name: '',
    username: "",
    password: '',
  })
  const sqlserver = JSON.parse(window.localStorage.getItem("sqlserver"))
  if (sqlserver != "") {
    formLabelAlign.ip = sqlserver.ip
    formLabelAlign.port = sqlserver.port
    formLabelAlign.name = sqlserver.name
    formLabelAlign.username = sqlserver.username
    formLabelAlign.password = sqlserver.password
  }

  function list() {
    List().then((res) => {
      tableNameOptions.value = res.data.map((item) => ({
        label: item,
        value: item,
      }));
    });
  }
  list();

  const handleSelectionChange = (val) => {
    multipleSelection.value = val
  }

  function tableChange(val) {
    Info(val).then((res) => {
      tableData.value = res.data;
    });
  }

  // 动态设置表格高度
  const getCardDetailsTableHeight = () => {
    let tableH = 20; //距离页面下方的高度
    let tableHeightDetil = window.innerHeight - tableH;
    if (tableHeightDetil <= 100) {
      windowHeight.value = 100;
    } else {
      windowHeight.value = window.innerHeight - tableH;
    }
  };

  const selectionValues = computed(() => multipleSelection.value);

  //生成代码
  const scdm = () => {
    if (tableName.value == "") {
      ElMessage.warning('请选择表');
      return
    }
    if (multipleSelection.value.length > 0) {
      var aa = multipleSelection.value
      aa.forEach(element => {
        console.log("选中的是", element)
      });
      entity.value = generateCSharpEntityClass(tableName.value, aa)
      insertText.value = insertC(tableName.value, aa)
      updateText.value = updateC(tableName.value, aa)
    } else {
      var aa = tableData.value
      entity.value = generateCSharpEntityClass(tableName.value, aa)
      insertText.value = insertC(tableName.value, aa)
      updateText.value = updateC(tableName.value, aa)
    }


  }

  // 监听窗口变化动态设置表格高度
  window.onresize = () => {
    getCardDetailsTableHeight();
  };

  //抽屉
  const handleClose = (done) => {
    ElMessageBox.confirm('Are you sure you want to close this?')
      .then(() => {
        done()
      })
      .catch(() => {
        // catch error
      })
  }

  //测试数据库是否可以连接
  function cheshi() {
    //jdbc:sqlserver://"+ip+";databaseName="+dataBaseName+";useAffectedRows=true;trustServerCertificate=true;
    if (formLabelAlign.ip == "") {
      ElNotification({
        title: '错误',
        message: '请输入数据库ip',
        type: 'error',
      })
      return
    }
    if (formLabelAlign.port == "") {
      ElNotification({
        title: '错误',
        message: '请输入端口',
        type: 'error',
      })
      return
    }
    if (formLabelAlign.name == "") {
      ElNotification({
        title: '错误',
        message: '请输入数据库名',
        type: 'error',
      })
      return
    }
    if (formLabelAlign.username == "") {
      ElNotification({
        title: '错误',
        message: '请输入数据库用户名',
        type: 'error',
      })
      return
    }
    if (formLabelAlign.password == "") {
      ElNotification({
        title: '错误',
        message: '请输入数据库密码',
        type: 'error',
      })
      return
    }
    var sqlBase = {}
    sqlBase.ip = formLabelAlign.ip
    sqlBase.port = formLabelAlign.port
    sqlBase.url = "jdbc:sqlserver://" + formLabelAlign.ip + ":" + formLabelAlign.port + ";DatabaseName=" + formLabelAlign.name + ";trustServerCertificate=true;"
    sqlBase.name = formLabelAlign.name
    sqlBase.username = formLabelAlign.username
    sqlBase.password = formLabelAlign.password
    console.log("切换数据库", sqlBase)
    qiehuansql(sqlBase)
  }

  //sqlserver 展示 切换
  function danqiansql() {
    Danqiansql().then(res => {
      console.log("当前连接是*---", res)
    })
  }
  danqiansql()
  function qiehuansql(data) {
    Qiehuansql(data).then(res => {
      if (res.data.url == "" || res.data.url == null) {
        ElNotification({
          title: '错误',
          message: '连接失败！！请检查数据库参数信息是否正确',
          type: 'error',
        })
      } else {
        ElNotification({
          title: '成功',
          message: '切换成功！！',
          type: 'success',
        })
        drawer.value = false
        window.localStorage.setItem('sqlserver', JSON.stringify(res.data))
        list()
      }
    })
  }

  //生成实体类
  function generateCSharpEntityClass(tableName, columns) {
    let classCode = `public class ${tableName} {\n`;

    for (let i = 0; i < columns.length; i++) {
      const column = columns[i];
      const { name, type, size, comment } = column;

      let comment1 = `    /// <summary>
    /// ${comment} => 备注: ${name}
    /// </summary>\n`
      let propertyCode = comment1 + `    public ${getCSharpDataType(type, size)} ${name} { get; set; }`;

      classCode += `${propertyCode}\n`;
    }

    classCode += '}';

    return classCode;
  }
  //数据库映射c#
  function getCSharpDataType(type, size) {
    switch (type) {
      case 'int':
        return 'int';
      case 'bigint':
        return 'long';
      case 'smallint':
        return 'short';
      case 'tinyint':
        return 'byte';
      case 'bit':
        return 'bool';
      case 'decimal':
      case 'numeric':
        return 'decimal';
      case 'real':
        return 'float';
      case 'float':
        return 'double';
      case 'money':
      case 'smallmoney':
        return 'decimal';
      case 'char':
      case 'nchar':
      case 'varchar':
      case 'nvarchar':
      case 'text':
      case 'ntext':
        if (size && size <= 8000) {
          return `string`;
        } else {
          return `string`;
        }
      case 'datetime':
      case 'smalldatetime':
        return 'DateTime';
      case 'date':
        return 'DateTime';
      case 'time':
        return 'TimeSpan';
      case 'datetime2':
        return 'DateTime';
      case 'datetimeoffset':
        return 'DateTimeOffset';
      case 'binary':
      case 'varbinary':
      case 'image':
        return 'byte[]';
      case 'uniqueidentifier':
        return 'Guid';
      // 添加更多的数据类型映射...
      default:
        return 'object';
    }
  }

  //生成插入代码--c#
  function insertC(tableName, columns) {
    let daima = `StringBuilder strSql = new StringBuilder();
strSql = new StringBuilder();
strSql.Append("insert into ${tableName}(");\n`
    daima += `strSql.Append("`
    for (let i = 0; i < columns.length; i++) {
      const column = columns[i];
      const { name } = column;
      daima += `${name}`
      if (i != columns.length - 1) {
        daima += ","
      }
    }
    daima += `)";\n`
    daima += `strSql.Append(" values (");\n`
    daima += `strSql.Append("`
    for (let i = 0; i < columns.length; i++) {
      const column = columns[i];
      const { name } = column;
      daima += `@${name}`
      if (i != columns.length - 1) {
        daima += ","
      }
    }
    daima += `);";\n`
    daima += `SQLString.Add(strSql, ); \n`
    return daima
  }

  //生成更新代码--c#
  function updateC(tableName, columns) {
    let daima = `strSql = new StringBuilder();\n`
    daima += `strSql.Append("update ${tableName} set ");\n`
    for (let i = 0; i < columns.length; i++) {
      const column = columns[i];
      const { name } = column;
      daima += `strSql.Append("${name}=@${name}`
      if (i != columns.length - 1) {
        daima += `,");\n`
      } else {
        daima += `");\n`
      }
    }
    daima += `strSql.Append(" where Id=@Id ");\n`
    daima += `SQLString.Add(strSql, item);`
    return daima
  }

  //复制文本
  const copyAnswer = async (copyData) => {
    console.log('copyData', copyData)
    if (copyData === '') {
      ElMessage.warning('有数据在复制');
      return
    }
    try {
      await toClipboard(copyData)
      ElMessage.success(`复制成功！`);
    } catch (error) {
      ElMessage.warning(`复制失败！`);
      console.error(error)
    }
  }

</script>

<style scoped>
  .parent {
    width: 95%;
    display: grid;
    grid-template-columns: 1fr;
    grid-template-rows: repeat(3, 1fr);
    grid-column-gap: 0px;
    grid-row-gap: 0px;
  }

  .div1 {
    grid-area: 1 / 1 / 2 / 2;
  }

  .div2 {
    grid-area: 2 / 1 / 3 / 2;
  }

  .div3 {
    grid-area: 3 / 1 / 4 / 2;
  }
</style>